home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
utils
/
chkpt10.zip
/
CHKPTBL.C
next >
Wrap
Text File
|
1996-04-05
|
28KB
|
868 lines
#ifndef __TINY__
#error Must be compiled in tiny model
#endif
/* *********************************************************************** */
/* This program compares the root sector (that is partition table for */
/* hard disks and boot sector for floppy disks) and, optionally (in the */
/* case of an hard disk), the boot sector with data stored in a supplied */
/* file. */
/* The data files could be generated always with this same program. */
/* A lot of options allow a full control of program, but has to be re- */
/* membered that such a program works at an intimate level with the com- */
/* computers hardware and so its use must be very careful. No warranties */
/* are given and the author could not be claimed responsible for damages */
/* produced by the use of the program. */
/* One possible use of this program is to save root and boot sector of */
/* the hard disk and check them every boot (inserting a command in the */
/* autoexec.bat file) to reveal undesired changes (maybe a virus) and e- */
/* ventually, with maximum care, restore the original data. */
/* */
/* syntax: */
/* CHKPTBL [switches] <file-name> */
/* <file-name> is the data file to compare root sector with. */
/* If no extension is present extension .TBL is added, if a di- */
/* rectory name is supplied (ending with '\') the default name */
/* PARTTBL.TBL is used. If no name is supplied no check is made. */
/* */
/* switches: */
/* */
/* /H[1..Number of physical hard drive - default 1] selects the phy- */
/* sical hard drive subsequent commands refer to. */
/* For default hard drive 1 is taken. */
/* /F[1..Number of physical floppy drive - default 1]selects the phy- */
/* sical floppy drive subsequent commands refer to. */
/* If /F with no number is specified physical floppy 1 is taken */
/* /S Stop if differences are found between data stored in the fi- */
/* le and actual root (boot) sector. */
/* /C If differences are found between data stored in the file and */
/* actual root (boot) sector, correct them restoring the data in */
/* file. */
/* /B[+|-] Set the "Check boot sector too" option true(/B+) or false */
/* (/B-). If this switch is not specified the option is false, */
/* if only /B is specified the option is set to true. */
/* /W[+]<file-name> Store drive-data to <file-name> (ext. and name as */
/* for reference file). If the file already exists, if /W+ is */
/* specified the file is overwritten, otherwise nothing is done. */
/* If the "Check boot sector too" option is actually true and */
/* the actually selected drive is an hard whose partition number */
/* one is a dos bootable partition even the boot sector is saved */
/* (for a total of 1024 bytes),otherwise only the root sector is */
/* written to the file. */
/* */
/* example: */
/* CHKPTBL /Wfile1 /B /H2 /Wfile2/F/Wfile3 /H/Wfile4 C:\DOS\ */
/* Actions: */
/* The root sector of hard drive 1 is written to file1, the root sec- */
/* tor of hard drive 2 (which is generally a not dos-bootable disk) is */
/* written to file2, the root sector (which is the boot sector) of the */
/* floppy drive 1 (usually a:) is written to file3 and the root sector */
/* and the first partition's boot sector (if it's a DOS-bootable par- */
/* tition) of the hard drive 1 are written to file4 and both are com- */
/* pared with the file C:\DOS\PARTTBL.TBL. */
/* */
/* (c) 1996 by Luigi Mancinelli */
/* manci@alpha.science.unitn.it */
/* */
/* Note: If the program has to be recompiled, the tiny model has to be */
/* used and the resulting .exe has to be converted in .com (with the DOS */
/* utility EXE2BIN for example) or the program doesn't work. */
/* */
/* *********************************************************************** */
#define NULL 0
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
void _Cdecl __int__(int interruptnum);
void __emit__();
/* extern unsigned _Cdecl _psp; */
#define SEG_FP(fp) (((unsigned int *) (&(fp)))[1])
#define OFS_FP(fp) ((unsigned int) (fp))
#include <dir.h>
#define _toupper(c) ((c)&0xDF)
#define putchar(c) (_DL=c,_AH=02,__int__(0x21))
#define putbackslash() (_DL='\\',_AH=02,__int__(0x21))
void putstring(char *p)
{ unsigned int i=0;
if (p!=NULL)
while (p[i]!=0) putchar(p[i++]);
}
char *HexDig="0123456789ABCDEF";
void puthexbyte(unsigned char ch)
{
putchar(HexDig[ch>>4]);
putchar(HexDig[ch&0xF]);
}
void newline(void)
{ putchar('\r'); putchar('\n'); }
typedef unsigned char byte;
typedef unsigned int word;
word DOSFileError=0;
word FCreate(const char far * filename, byte fmode)
{
word SaveDS;
SaveDS=_DS;
_CX=fmode;
_AH=0x3C;
_DS=SEG_FP(filename);
_DX=OFS_FP(filename);
__int__(0x21);
_DS=SaveDS;
__emit__(0xBB,0x00,0x00,0x73,0x02,0x87,0xC3);
/* MOV BX,0 - JNC L1 - XCHG AX,BX - L1: */
/* IF CY THEN _BX=_AX _AX=0 ELSE _BX=0 */
DOSFileError=_BX;
return _AX;
}
word FOpen(const char far * filename, byte fmode)
{
word SaveDS;
SaveDS=_DS;
_AH=0x3D; _AL=fmode;
_DS=SEG_FP(filename);
_DX=OFS_FP(filename);
__int__(0x21);
_DS=SaveDS;
__emit__(0xBB,0x00,0x00,0x73,0x02,0x87,0xC3);
/* MOV BX,0 - JNC L1 - XCHG AX,BX - L1: */
/* IF CY THEN _BX=_AX _AX=0 ELSE _BX=0 */
DOSFileError=_BX;
return _AX;
}
int FRead(word handle, byte far * buffer,
word BytesToRead, word far *BytesRead)
{
word SaveDS;
SaveDS=_DS;
_AH=0x3F;
_BX=handle;
_DS=SEG_FP(buffer);
_DX=OFS_FP(buffer);
_CX=BytesToRead;
__int__(0x21);
_DS=SaveDS;
__emit__(0xBB,0x00,0x00,0x73,0x02,0x87,0xC3);
/* MOV BX,0 - JNC L1 - XCHG AX,BX - L1: */
/* IF CY THEN _BX=_AX _AX=0 ELSE _BX=0 */
DOSFileError=_BX;
*BytesRead=_AX;
if (DOSFileError) return -1;
else if (_AX==0) return 1;
else if (_AX<BytesToRead) return 2;
else return 0;
}
int FWrite(word handle, byte far * buffer,
word BytesToWrite, word far *BytesWritten)
{
word SaveDS;
SaveDS=_DS;
_AH=0x40;
_BX=handle;
_DS=SEG_FP(buffer);
_DX=OFS_FP(buffer);
_CX=BytesToWrite;
__int__(0x21);
_DS=SaveDS;
__emit__(0xBB,0x00,0x00,0x73,0x02,0x87,0xC3);
/* MOV BX,0 - JNC L1 - XCHG AX,BX - L1: */
/* IF CY THEN _BX=_AX _AX=0 ELSE _BX=0 */
DOSFileError=_BX;
*BytesWritten=_AX;
if (DOSFileError) return -1;
else if (_AX==0) return 1;
else if (_AX<BytesToWrite) return 2;
else return 0;
}
int FClose(word handle)
{
_AH=0x3E;
_BX=handle;
__int__(0x21);
__emit__(0xBB,0x00,0x00,0x73,0x02,0x87,0xC3);
/* MOV BX,0 - JNC L1 - XCHG AX,BX - L1: */
/* IF CY THEN _BX=_AX _AX=0 ELSE _BX=0 */
DOSFileError=_BX;
if (_BX) return -1; else return 0;
}
#define B_READ 0x2
#define B_WRITE 0x3
#define B_VERIFY 0x4
/* biosdisk */
int ResetDrives(byte drive)
{
_AH=0;
_DL=drive /* 0x80 */;
__int__(0x13);
/* __emit__(0x73,0x02,0xB4,0x00); */
/* JNC L1 - MOV AH,0 - L1: */
/* IF CY THEN _AH=ERROR ELSE _AH=0 */
return _AH;
}
int _HardDrives(void)
{
_AH=0x8;
_DL=0x80;
__int__(0x13);
return _DL;
}
int _FloppyDrives(void)
{
_AH=0x8;
_DL=0;
__int__(0x13);
return _DL;
}
int _BiosDiskLL(byte func, byte drive, byte head, word tracksect,
void far * BuffOfs)
{
_ES=((word *) (&BuffOfs))[1];
_DL=drive /* 0x80 */;
_CX=tracksect; /* _CH=track; _CL=sectnum; */
_DH=head;
_BX=*((word *) (&BuffOfs));
_AH=func;
_AL=1;
__int__(0x13);
/* __emit__(0x73, 0x02, 0xB4, 0x00); */
/* JNC L1 -- MOV AH,0 -- L1: */
return _AH;
}
int ReadSectorLL(byte drive, byte head, word tracksect,
void far * BuffOfs)
{
int i,done,Err;
for (i=done=0; i<3; i++) {
if((Err=_BiosDiskLL(B_READ,drive,head,tracksect,BuffOfs))==0)
{ done=1; break; }
ResetDrives(drive);
}
if(done==0) return Err;
else return 0;
}
int WriteSectorLL(byte drive, byte head, word tracksect,
void far * BuffOfs)
{
int i,done,Err;
for (i=done=0; i<3; i++) {
if((Err=_BiosDiskLL(B_WRITE,drive,head,tracksect,BuffOfs))==0)
{ done=1; break; }
ResetDrives(drive);
}
if(done==0) return Err;
else return _BiosDiskLL(B_VERIFY,drive,head,tracksect,BuffOfs);
}
char *stradd(char *Dest, const char *ToAdd)
{
unsigned int i=0,j=0,ilim,jlim;
/*
unsigned int j=0;
unsigned int ilim,jlim;
*/
ilim=(unsigned int) Dest;
ilim=65535-ilim;
jlim=(unsigned int) ToAdd;
jlim=65535-jlim;
while ((i<=ilim)&&(Dest[i]!=0)) i++;
while ((i<=ilim)&&(j<=jlim)&&(ToAdd[j]!=0)) Dest[i++]=ToAdd[j++];
if(i<=ilim) Dest[i]=0;
return Dest;
}
#define IsInSet(ch,Set) ((Set[ch>>3]>>(ch&7))&1)
/* errors (<0 ) */
#define FNInvalidChar -1
#define FNInvalidDrive -2
#define FNInvalidPath -4
#define FNBlankUnacceptable -8
#define FNPointUnacceptable -16
#define FNInvalidNetName -32
#define FNPathToLong -64
#define FNPathNameToLong -128
/* informations */
#define FNNetName 1
#define FNNoName 2
#define FNJollyInName 4
#define FNJollyInExt 8
#define FNJolly 12
#define FNExtPres 16
#define FNNoNullExt 32
#define FNIsPathName 64
#define FNBlankPresent 128
#define FNJollyInPath 256
/* parsing options */
#define FNStopOnInvalidChar 1
#define FNAcceptJollyInPath 2
#define FNAcceptBlank 4
#define FNCheckDevName 8
#define FNTerminChar 16
char FlNmSetOfUnaccChars[32]={
0xFF,0xFF,0xFF,0xFF,0x04,0xD8,0x00,0x7C,
0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x10,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
/* FlPathNmUnaccChs :Set Of Char=
[#0..#31,'"','+',',','.','/',
':',';','<','=','>','[','\',']','|'];
*/
int TrueName(int *Drive, char *pathname, char**name, char *src,
int *pos, int Param)
{
#define STARINNAME 2
#define STARINEXT 4
#define DEVNAME 8
int i,j,strtp,strtn,strte,l;
char Fnd;
char ch1,ch2;
char TermChar=0;
int Error=0;
#define ErrorANDReset (~((unsigned int) FNJollyInName | FNJollyInExt | \
FNExtPres | FNNoNullExt))
*Drive=0;
strte=i=j=0;
Fnd=0;
/* adjust src pointer */
src=&(src[*pos]); /* caveat programmer: (*pos)<strlen(src) */
if((Param & FNTerminChar)!=0)
{ TermChar=Param>>8; /* printf("\a\a(Term on %d)\n",TermChar); */ }
*name=&(pathname[0]);
if(((ch1=(pathname[0]=src[0]))==0)||(ch1==TermChar)) return pathname[0]=0;
if(((ch2=(pathname[1]=src[1]))==0)||(ch2==TermChar)) {
if(ch2!=0) pathname[1]=0;
if(ch1=='.') {Error=FNPointUnacceptable; pathname[0]=0;}
else if(ch1=='\\') {*name=&(pathname[1]); (*pos)++; Error|= FNNoName;}
else if(IsInSet(ch1,FlNmSetOfUnaccChars)==0) (*pos)++;
else { Error=FNInvalidChar; pathname[0]=0; }
return Error;
}
if(ch2==':') {
if((((*Drive)=_toupper(ch1)-65)<0)||((*Drive)>=setdisk(getdisk())) )
return FNInvalidDrive; /* invalid Drive specification */
else {i=j=strtn=strtp=2;}
}
else if((ch1=='\\')&&(ch2=='\\')) {
/* machine specification found */
i=j=strtn=2; strtp=-1;
Error|=FNNetName;
}
else strtn=strtp=0;
while ((Error>=0)&&(Fnd!=-1)&&
((ch1=(pathname[i++]=src[j++]))!=0)&&(ch1!=TermChar)) {
if((i>92)||(((Error & FNNetName==0))&&(i>80))) Error=FNPathNameToLong;
else
switch (ch1) {
case '.' :if(strte!=0)
/* not valid point in this pos. */
Error=FNPointUnacceptable;
else if((i-1)>strtn) {
if(src[j]=='\\') i--;
else {Fnd=0; strte=i; Error|=FNExtPres; }
}
else if(strtp==-1) Error=FNInvalidNetName;
/* not valid as a machine specification */
else if((ch2=src[j])==0) Error=FNPointUnacceptable;
else if(ch2=='\\') {
if((strtn>strtp)|| ((i>3)&&(pathname[i-2]=='\\')
&&(pathname[i-3]=='.')) ) { i--; if(i==strtn)j++; }
}
else if((ch2=='.')&&(src[j+1]=='\\')) {
/* ..\ */
if((i>=2)&&((i-2)==strtp)&&(pathname[i-2]=='\\'))
Error=FNInvalidPath;
else if((i-1)==strtp){
pathname[i++]='.'; pathname[i++]='\\';
j+=2; strtn=strtp=i;
}
else {
i-=3;
while((i>=strtp)&&(pathname[i]!='\\')) i--;
if(Param & FNAcceptJollyInPath) {
Error&= ~FNJollyInPath;
for(l=strtp; l<i; l++)
if((pathname[l]=='?')||(pathname[l]=='*') )
Error|= FNJollyInPath;
}
j+=2; strtn=++i;
}
}
else Error=FNPointUnacceptable;
break;
case '\\':if(((i-1)==strtn)&&(strtn!=strtp)) Error=FNInvalidChar;
else {
if(strtp==-1) strtp=i;
else {
if(Error & FNJolly) {
if ((Param & FNAcceptJollyInPath)==0)
Error=FNInvalidPath;
else Error|= FNJollyInPath;
}
}
if((i-strtp)>66) Error=FNPathToLong;
else {
Error&= ErrorANDReset;
strtn=i; strte=0; Fnd=0;
}
}
break;
case '?' :
case '*' :if(strtp==-1) Error=FNInvalidNetName;
else if(Fnd|| (((strte>0)&&((i-strte)>3))||
((strte==0)&&((i-strtn)>8)) ) ) i--;
else {
if(strte==0) Error|= FNJollyInName;
else Error|= FNNoNullExt | FNJollyInExt;
if(ch1=='*') Fnd=1;
/* Once it's true it doesn't become false until
'\' or '.' is found */
}
break;
default :/* if ch1 in invalid chars ... stop */
if ((IsInSet(ch1,FlNmSetOfUnaccChars)!=0)||
((ch1==' ')&&((Param & FNAcceptBlank)==0)) ) {
if(Param & FNStopOnInvalidChar) Fnd=-1;
else Error=FNInvalidChar;
}
else if((ch1==' ')&&((i-1)==strtn))Error=FNBlankUnacceptable;
else if(Fnd|| (((strte>0)&&((i-strte)>3))||
((strte==0)&&((i-strtn)>8)) ) ) i--;
else {
if(strte>0) Error|= FNNoNullExt;
if(ch1==' ') Error|= FNBlankPresent;
}
}
}
if(Error>=0) {
if(strtp==-1) /* machine name */ ;
(*pos)+=j-1;
if(ch1!=0)pathname[i-1]=0;
*name=&(pathname[strtn]);
if(pathname[strtn]==0) Error|= FNNoName;
} else { (*pos)+=j-1; pathname[i-1]=0; }
return Error;
#undef ErrorANDReset
}
#define CR 0x0D
/* *************************** */
byte *CmdStr=(byte *) 0x80;
int pos=1;
void SkipBlanks(void) {
while ((CmdStr[pos]==' ')||(CmdStr[pos]==9)) pos++;
}
#define INVALIDSWITCH -1
#define INVALIDDRIVE -2
#define INVALIDPATH -3
#define PATHTOLONG -4
#define PATHNAMETOLONG -5
#define UNACCEPTABLECHAR -6
#define UNTERMINATEDSTRING -7
#define JOLLYUNACCEPTED -8
#define ROOTUNREADABLE -10
#define EE_UNREADABLE 1
#define EE_UNWRITABLE 2
#define EE_NOTCHECKED 4
#define EE_BOOTNOTCHECKED 8
#define EE_ERRORINREADING 16
#define EE_ERRORINWRITING 32
#define EE_CORRECTED 128
char *ErrMess[8]={" Invalid switch or syntax error",
" Invalid drive"," Invalid path",
" - path to long"," - path name to long",
" unacceptable char"," expected -- Unterminated string",
" -- Jolly unaccepted"};
#define READ 1
#define WRITE 0
#define BOOT 1
#define ROOT 0
char *UnableTo="\7\7Unable to ";
char *Read="read ";
char *Write="write ";
char *Sector="oot sector\r\n";
int putUnableTo(int rd, int bt)
{
putstring(UnableTo);
if(rd==READ) putstring(Read); else putstring(Write);
if(bt==BOOT) putchar('b'); else putchar('r');
putstring(Sector);
}
char *SkipExisting="Skip existing";
char *MaybeDiskFull="Unable to write data (maybe disk-full) to";
char *NotGoodFile="Not good";
char *File=" file ";
#define OPENING 0
#define READING 1
#define CLOSING 2
#define CREATING 3
#define WRITING 4
char *DosErrWhile[5]={"opening","reading","closing","creating","writing to"};
int putDOSError(int ErrWhile, char * FileName)
{
putstring("DOS error "); puthexbyte(DOSFileError); putstring(" in ");
putstring(DosErrWhile[ErrWhile]); putstring(File);
putstring(FileName);
newline();
}
char *NotEquals="oot Sector and ref. file are not equal\r\n\7\7\7";
byte HDrives;
byte FDrives;
char FlName[92];
char Opened[92];
char *Name;
word IHandle=0;
word OHandle=0;
byte OverWrite=0;
char SwitchChar='/';
int Error=0;
int FnError=0;
int FnParam=0;
byte ExitError=0;
char AutoCorrect=0;
char StopOnError=0;
byte Drive=0x80;
byte Partition=0;
int PartOfs=0x1BE;
byte ReadRoot=1;
byte BootToo=0;
byte RootSect[1024];
byte Buffer[1024];
word RW_size=512;
word i;
char Ch,c;
int BootPartition(byte *Root)
{
byte System;
PartOfs=0x1BE+16*Partition;
System=Root[PartOfs+04];
return (Root[PartOfs]==0x80)&&
((System==01)||(System==04)||(System==06));
}
int ReadPTable(void)
{
ResetDrives(Drive);
if(ReadRoot==1) {
if(ReadSectorLL(Drive,0,1,(void far *) (RootSect))==0) {
ReadRoot=0;
ExitError&=~EE_UNREADABLE;
if(BootToo && (Drive & 0x80) && BootPartition(RootSect)) {
if(ReadSectorLL(Drive,RootSect[PartOfs+1],
*((word *)&(RootSect[PartOfs+2])),
(void far *) &(RootSect[512]))==0) {
RW_size=1024;
ExitError&=~EE_BOOTNOTCHECKED;
}
else {
ReadRoot=3;
putUnableTo(READ,BOOT);
ExitError|=~EE_UNREADABLE;
}
}
else {
RW_size=512;
if(BootToo && (Drive & 0x80)) ExitError|=EE_BOOTNOTCHECKED;
}
}
else {
ReadRoot=2;
putUnableTo(READ,ROOT);
ExitError|=EE_UNREADABLE;
}
}
return ReadRoot;
}
int WritePTable(void)
{
ResetDrives(Drive);
if(WriteSectorLL(Drive,0,1,(void far *) (Buffer))==0) {
if(BootToo && (Drive & 0x80) && BootPartition(Buffer)) {
if(WriteSectorLL(Drive,Buffer[PartOfs+1],
*((word *)&(Buffer[PartOfs+2])),
(void far *) &(Buffer[512]))!=0) {
putUnableTo(WRITE,BOOT);
ExitError|=~EE_UNWRITABLE;
}
}
else if(BootToo && (Drive & 0x80)) ExitError=EE_BOOTNOTCHECKED;
}
else {
putUnableTo(WRITE,ROOT);
ExitError|=EE_UNWRITABLE;
}
return ((ExitError & EE_UNWRITABLE)!=0);
}
int IsGoodSeparator(unsigned char Ch)
{
return ((Ch==' ')||(Ch==9)||(Ch==CR)||(Ch==SwitchChar));
}
int CheckIfInvalid(char c)
{
if(!IsGoodSeparator(c)) {
putchar('/'); putchar(Ch); Error=INVALIDSWITCH;
}
return Error==INVALIDSWITCH;
}
int GetFileName(void)
{
int Drive;
char FndCh;
FnParam=FNTerminChar|(((word) CR)<<8)|FNStopOnInvalidChar;
if ((Ch=='"')||(Ch=='[')) {
pos++; if (Ch=='"') FndCh='"'; else FndCh=']';
FnParam|=FNAcceptBlank;
} else FndCh=0;
FnError=TrueName((int *)&i,FlName,&Name,CmdStr,&pos,FnParam);
if(FnError<0) {
if(FnError==FNInvalidDrive) Error=INVALIDDRIVE;
else if(FnError==FNInvalidPath) Error=INVALIDPATH;
else if(FnError==FNPathToLong) Error=PATHTOLONG;
else if(FnError==FNPathNameToLong) Error=PATHNAMETOLONG;
else Error=UNACCEPTABLECHAR;
}
else if(FndCh!=0){
if(CmdStr[pos]==FndCh) pos++;
else if(CmdStr[pos]=='\r') Error=UNTERMINATEDSTRING;
else Error=UNACCEPTABLECHAR;
}
else if(!IsGoodSeparator(CmdStr[pos])) Error=UNACCEPTABLECHAR;
else if(FnError&FNJolly) Error=JOLLYUNACCEPTED;
if(Error==0) {
if(FnError & FNNoName) stradd(FlName,"PARTTBL.TBL");
else if((FnError & FNExtPres)==0) stradd(FlName,".TBL");
}
return Error;
}
int cdecl main() {
/*
unsigned int DS=((unsigned long)((char far *)(&CmdStr)))>>16;
if(DS==_psp) { */
i=CmdStr[0];
if(CmdStr[i+1]!=CR) CmdStr[i+1]=CR;
HDrives=_HardDrives();
FDrives=_FloppyDrives();
/*
putchar(HDrives+0x30); putstring(" hard disks and ");
putchar(FDrives+0x30); putstring(" floppy disks\r\n");
*/
SkipBlanks();
while ((Error==0)&&((Ch=CmdStr[pos])!=0xD)) {
if (Ch==SwitchChar) {
switch (Ch=_toupper(CmdStr[++pos])) {
case 'S': StopOnError=1; CheckIfInvalid(CmdStr[++pos]); break;
case 'C': AutoCorrect=1; CheckIfInvalid(CmdStr[++pos]); break;
case 'B': if(((c=CmdStr[++pos])=='-')||(c=='+')) {
pos++;
BootToo=(c=='+');
}
else BootToo=1;
if((CheckIfInvalid(CmdStr[pos]))&&(c!=CmdStr[pos]))
putchar(c);
ReadRoot=1;
break;
case 'F':
case 'H': i=Drive;
if(IsGoodSeparator(c=CmdStr[++pos])) {
Drive=0; if(Ch=='H') Drive|=0x80;
}
else if((c<'1')||(c>'9')) {
putchar('/'); putchar(Ch);
Error=INVALIDSWITCH;
}
else {
pos++;
if(((c<=(0x30+HDrives))&&(Ch=='H'))||
((c<=(0x30+FDrives))&&(Ch=='F')) ) {
Drive=(c-0x31); if(Ch=='H') Drive|=0x80;
}
}
if (Drive!=i) ReadRoot=1;
break;
case 'W':
if ((Ch=CmdStr[++pos])=='+') {
OverWrite=1;
pos++;
}
else OverWrite=0;
if(GetFileName()==0) {
if(ReadPTable()==0) {
OHandle=0;
if(OverWrite==0) {
OHandle=FOpen(FlName,0);
if (OHandle!=0) {
FClose(OHandle);
putstring(SkipExisting); putstring(File);
putstring(FlName); newline();
}
}
if(OHandle==0) {
OHandle=FCreate(FlName,0);
if (OHandle==0) putDOSError(CREATING,FlName);
else
if(FWrite(OHandle,(byte far *)RootSect,RW_size,&i)){
ExitError|=EE_ERRORINWRITING;
if(DOSFileError==0) {
putstring(MaybeDiskFull);
putstring(File); putstring(FlName); newline();
}
else putDOSError(WRITING,FlName);
}
if(FClose(OHandle)) putDOSError(CLOSING,FlName);
}
}
}
break;
default:
putchar('/');
Error=INVALIDSWITCH;
}
}
else {
if(GetFileName()==0) {
if (IHandle==0) {
IHandle=FOpen(FlName,0);
if (IHandle==0) putDOSError(OPENING,FlName);
else {
Opened[0]=0;
stradd(Opened,FlName);
}
}
}
}
if (ReadRoot==2) {
if(IHandle!=0) FClose(IHandle);
Error=ROOTUNREADABLE;
}
else if (Error<0) {
if(Error!=INVALIDSWITCH) putstring(FlName);
if(CmdStr[pos]!=CR) putchar(CmdStr[pos]);
putstring(ErrMess[-Error-1]);
if(IHandle!=0) FClose(IHandle);
}
else SkipBlanks();
}
if((Error==0)&&(IHandle!=0)) {
i=RW_size;
if(BootToo && (Drive & 0x80)) RW_size=1024; else RW_size=512;
if(i!=RW_size) ReadRoot=1;
if(FRead(IHandle,(char far *) Buffer,RW_size,&i)){
if((i==512)&&(BootToo)&&(!BootPartition(Buffer))) {
BootToo=0;
ExitError|=EE_BOOTNOTCHECKED;
}
else {
ExitError|=EE_ERRORINREADING | EE_NOTCHECKED;
if(DOSFileError==0) {
putstring(NotGoodFile); putstring(File);
putstring(Opened); newline();
}
else putDOSError(READING,Opened);
}
}
if(FClose(IHandle)) putDOSError(CLOSING,Opened);
if((ExitError & EE_ERRORINREADING)==0) {
/* Confronting message */
putstring("Confronting root ");
if(BootToo) putstring ("and boot ");
putstring("sector with"); putstring(File);
putchar('['); putstring(Opened); putchar(']');
/* putchar('('); puthexword(IHandle); putchar(')'); */
newline();
/* ******************* */
if((ReadPTable()==0)||(ReadRoot==3)) {
Ch=0;
for (i=0; i<RW_size; i++)
if (RootSect[i]!=Buffer[i]) { Ch=1; break; }
if(Ch==1) {
if(i<512) putchar('R'); else putchar('B');
putstring(NotEquals);
if(AutoCorrect) {
if(!WritePTable()) ExitError|=EE_CORRECTED;
}
if(StopOnError) {
putchar('\7'); putchar('\7');
while (1);
}
}
}
}
}
else ExitError|=EE_NOTCHECKED;
return ExitError;
/* } */
#if 0
for (i=0; i<200; i++) {
putchar(((byte far *) (_ReadRootSector /* FOpen */))[i]);
}
#endif
}